// UserChatWebSocketServer.java
package org.example.websocket;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import org.example.model.ChatMessage;
import org.example.model.UserInfo;
import org.example.model.UserOnlineMessage;
import org.example.service.ChatMessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.websocket.*;
import javax.websocket.server.ServerEndpoint;
import javax.websocket.server.PathParam;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@ServerEndpoint("/ws/user/{username}")
@Component
public class UserChatWebSocketServer {
    private static final Logger logger = LoggerFactory.getLogger(UserChatWebSocketServer.class);
    
    // 使用用户名作为key存储session
    private static final Map<String, Session> USER_SESSIONS = new ConcurrentHashMap<>();
    
    // 静态注入 ChatMessageService
    private static ChatMessageService chatMessageService;
    
    @Autowired
    public void setChatMessageService(ChatMessageService service) {
        chatMessageService = service;
    }

    @OnOpen
    public void onOpen(Session session, @PathParam("username") String username) {
        if (username == null || username.trim().isEmpty()) {
            try {
                session.close();
                logger.error("WebSocket连接失败：未提供用户名");
                return;
            } catch (IOException e) {
                logger.error("关闭无效连接失败", e);
            }
            return;
        }
        
        logger.info("用户WebSocket连接建立, username: {}", username);
        
        // 检查是否存在旧连接
        Session oldSession = USER_SESSIONS.get(username);
        if (oldSession != null) {
            try {
                oldSession.close();
                logger.info("关闭用户 {} 的旧连接", username);
            } catch (IOException e) {
                logger.error("关闭旧连接失败", e);
            }
        }
        
        // 保存新的session
        USER_SESSIONS.put(username, session);
        
        // 保存用户信息到session
        session.getUserProperties().put("userId", username);
        session.getUserProperties().put("username", username);
        
        // 发送连接成功消息给用户
        ChatMessage message = new ChatMessage();
        message.setType("SYSTEM");
        message.setContent("连接成功");
        message.setTimestamp(System.currentTimeMillis());
        message.setFromCustomerService(false);
        message.setFromSystem(true);
        message.setToId(username);
        
        try {
            String jsonMessage = JSON.toJSONString(message);
            session.getBasicRemote().sendText(jsonMessage);
            logger.info("发送连接成功消息: {}", jsonMessage);
            
            // 通知客服有新用户上线
            UserInfo userInfo = new UserInfo();
            userInfo.setUserId(username);
            userInfo.setUsername(username);
            
            UserOnlineMessage onlineMessage = new UserOnlineMessage();
            onlineMessage.setType("USER_ONLINE");
            onlineMessage.setUser(userInfo);
            
            String onlineJsonMessage = JSON.toJSONString(onlineMessage);
            CustomerServiceWebSocketServer.broadcastToCustomerService(onlineJsonMessage);
        } catch (IOException e) {
            logger.error("发送连接成功消息失败", e);
        }
    }
    
    @OnMessage
    public void onMessage(String message, Session session) {
        String userId = (String) session.getUserProperties().get("userId");
        String username = (String) session.getUserProperties().get("username");
        logger.info("收到用户 {} ({}) 的消息: {}", username, userId, message);

        try {
            // 解析接收到的消息
            ChatMessage chatMessage = JSON.parseObject(message, ChatMessage.class);
            chatMessage.setFromId(userId);
            chatMessage.setFromName(username);
            chatMessage.setTimestamp(System.currentTimeMillis());
            chatMessage.setFromCustomerService(false);
            
            // 保存消息到MongoDB
            chatMessageService.saveMessage(chatMessage);
            
            // 将消息广播给客服
            CustomerServiceWebSocketServer.broadcastToCustomerService(JSON.toJSONString(chatMessage));
            
            // 回显消息给用户自己
            session.getBasicRemote().sendText(JSON.toJSONString(chatMessage));
            
            logger.info("消息已保存到MongoDB并转发给客服和用户");
        } catch (Exception e) {
            logger.error("处理用户消息失败: {}", e.getMessage());
            try {
                // 发送错误消息给用户
                ChatMessage errorMessage = new ChatMessage();
                errorMessage.setType("ERROR");
                errorMessage.setContent("消息发送失败，请重试");
                errorMessage.setTimestamp(System.currentTimeMillis());
                errorMessage.setToId(userId);
                errorMessage.setFromSystem(true);
                
                // 保存错误消息到MongoDB
                chatMessageService.saveMessage(errorMessage);
                
                session.getBasicRemote().sendText(JSON.toJSONString(errorMessage));
            } catch (IOException ex) {
                logger.error("发送错误消息失败: {}", ex.getMessage());
            }
        }
    }
    
    @OnClose
    public void onClose(Session session) {
        String username = (String) session.getUserProperties().get("username");
        logger.info("用户WebSocket连接关闭: {}", username);
        
        // 从会话映射中移除
        USER_SESSIONS.remove(username);
        
        // 通知客服用户已下线
        if (username != null) {
            try {
                JSONObject offlineMessage = new JSONObject();
                offlineMessage.put("type", "USER_OFFLINE");
                offlineMessage.put("userId", username);
                
                String jsonMessage = offlineMessage.toJSONString();
                CustomerServiceWebSocketServer.broadcastToCustomerService(jsonMessage);
            } catch (Exception e) {
                logger.error("通知客服用户下线失败", e);
            }
        }
    }
    
    @OnError
    public void onError(Session session, Throwable error) {
        logger.error("用户WebSocket错误: {}", error.getMessage());
    }

    // 发送消息给指定用户
    public static void sendToUser(String userId, String message) {
        USER_SESSIONS.values().stream()
                .filter(session -> userId.equals(getUserIdFromSession(session)))
                .findFirst()
                .ifPresent(session -> {
                    try {
                        session.getBasicRemote().sendText(message);
                        logger.info("消息已发送给用户 {}", userId);
                    } catch (IOException e) {
                        logger.error("发送消息给用户 {} 失败", userId, e);
                    }
                });
    }

    // 从Session中获取用户ID的辅助方法
    private static String getUserIdFromSession(Session session) {
        return (String) session.getUserProperties().get("username");
    }
}